home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / console / svgatext.3 / svgatext / SVGATextMode-1.3 / std_clock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-24  |  8.2 KB  |  286 lines

  1. /*  SVGATextMode -- An SVGA textmode manipulation/enhancement tool
  2.  *
  3.  *  Copyright (C) 1995,1996  Koen Gadeyne
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20.  
  21. /***
  22.  *** SVGA clock programming functions for SVGATextMode
  23.  ***
  24.  *** Almost all this code is adapted from the XFree86 3.1.1 or 3.1.2 code
  25.  *** See the XFree86 distribution for copyrights and authors
  26.  ***/
  27.  
  28. #include <stdio.h>
  29. #include <unistd.h>
  30. #ifndef DOS
  31. #  include <asm/io.h>
  32. #endif
  33. #include <math.h>
  34. #include "misc.h"
  35. #include "vga_prg.h"
  36. #include "std_clock.h"
  37. #include "clockchip.h"
  38. #include "messages.h"  
  39.  
  40.  
  41. void LegendClockSelect(int no)
  42.  /* used in both S3 and ET4000 cards (according to XFREE 3.1.1) */
  43. {
  44.   PDEBUG(("Using Sigma Legend clock selection\n"));
  45.   outb((inb(VGA_MISC_R) & 0xF3) | ((no & 0x10) >> 1) | (no & 0x04), VGA_MISC_W);
  46.   Outb_CRTC(0x34, 0x00);
  47.   Outb_CRTC(0x34, 0x02);
  48.   Outb_CRTC(0x34, (no & 0x08) >> 2);
  49.   SET_CLOCKBITS_0_1(no);
  50. }
  51.  
  52.  
  53. void TVGAClockSelect(int chipset, int num_clocks, int no)
  54. {
  55.     PDEBUG(("TVGAClockSelect: clock no %d (of total %d) for chipset %d.\n", no, num_clocks, chipset));
  56.     SET_CLOCKBITS_0_1(no);
  57.     Outb_SEQ(0x0B, 0); Inb_SEQ(0x0B);  /* Select "new mode regs" for CS2 and TVGA9000 CS3. */
  58. #if 0
  59.     Outb_SEQ(0x0D, Inb_SEQ(0x0D) & 0xF9);  /* set clock dividers to no division */
  60. #else
  61.     Outbit_SEQ(0x0D, 1, 0);  /* set clock dividers (div 2) to no division */
  62.     Outbit_SEQ(0x0D, 2, 0);  /* set clock dividers (div 4 ?) to no division */
  63. #endif    
  64.     Outbit_SEQ(0x0D, 0, no & 0x04);  /* bit 2 of clock no */
  65.     if (chipset == CS_TVGA9000)
  66.     {
  67.        Outbit_SEQ(0x0D, 6, no & 0x08);  /* bit 3 of clock no */
  68.     }
  69.     if ((chipset == CS_TVGA8900) && (num_clocks > 7))
  70.     {
  71.        Outb_SEQ(0x0B, 0);    /* Switch to Old Mode for CS3 */
  72.        Outbit_SEQ(0x0E, 4, no & 0x08);      /* bit 3 of clock no */
  73.     }
  74. }
  75.  
  76.  
  77. void s3ClockSelect(int no)
  78. {
  79.    if (OFLG_ISSET(OPT_LEGEND)) LegendClockSelect(no);
  80.    else
  81.    {
  82.      SET_CLOCKBITS_0_1(3);    /* select clock #3 to allow extra clocks to be used */
  83.      Outb_CRTC(0x42, no & 0x0f);
  84.    }
  85. }
  86.  
  87.  
  88. void ATIClockSelect(int chipset, int no)
  89. {
  90.    /* for MACH32 chipsets, bits 2 and 3 of the clock selection number must be
  91.       exchanged to comply with the XFREE MACH server clock ordering.
  92.       Derived through experimentation */
  93.    if (chipset==CS_ATIMACH32) no = ( no & 0xfffffff3) | ((no & 0x04)<<1) | ((no & 0x08)>>1);
  94.    ATI_PUTEXTREG(0xBE, (ATI_GETEXTREG(0xBE) & 0xEF) | ((no << 2) & 0x10));  /* clock bit 2 */
  95.    ATI_PUTEXTREG(0xB9, (ATI_GETEXTREG(0xB9) & 0xFD) | ((no >> 2) & 0x02));  /* clock bit 3 */
  96.    ATI_PUTEXTREG(0xB8, (ATI_GETEXTREG(0xB8) & 0x3F) | ((no << 2) & 0xC0));  /* clock divider */
  97.    SET_CLOCKBITS_0_1(no);    /* clock bits no 0 and 1 , must be set LAST */
  98.  }
  99.  
  100.  
  101. void WDCClockSelect(int chipset, int num_clocks, int no)
  102. {
  103.   int MClkIndex = 8;
  104.   int save_cs2 = 0;
  105.  
  106.   if ((chipset == CS_WDC90C1X) || (chipset == CS_WDC90C2X) || (chipset ==CS_WDC90C3X))
  107.     if (OFLG_ISSET(OPT_SWAP_HIBIT)) save_cs2 = 0; else save_cs2 = 4;
  108.   else
  109.     if (OFLG_ISSET(OPT_SWAP_HIBIT)) save_cs2 = 4; else save_cs2 = 0;
  110.  
  111.   if (num_clocks > 8) MClkIndex = num_clocks - 1;
  112.  
  113.   if ((no == MClkIndex) && (chipset != CS_PVGA1))
  114.   {
  115.     /*
  116.      * On all of the chipsets after PVGA1, you can feed MCLK as VCLK.
  117.      */
  118.     PDEBUG(("WDCClockSelect: Selecting MCLOCK as VCLOCK\n"));
  119.     Outbit_CRTC(0x2E, 4, 1);
  120.   }
  121.   else
  122.   {
  123.     /*
  124.      * Disable feeding MCLK to VCLK
  125.      */
  126.     if (chipset != CS_PVGA1) Outbit_CRTC(0x2E, 4, 0);
  127.  
  128.     SET_CLOCKBITS_0_1(no);
  129.     
  130.   if ((chipset != CS_PVGA1) && (chipset != CS_WDC90C0X))
  131.     Outbit_GR_CTL(0x0C, 1, (no & 0x04) ^ save_cs2); /* bit 2 of clock no */ 
  132.   if (chipset==CS_WDC90C3X)
  133.     Outbit_SEQ(0x12, 2, (no & 0x08) ^ 0x08); /* inverse clock bit 3 */
  134.   }
  135. }
  136.  
  137.  
  138. void ET4000ClockSelect(int no)
  139. {
  140.    int hibit = 1;
  141.    if (OFLG_ISSET(OPT_HIBIT_HIGH)) hibit = 1;
  142.    if (OFLG_ISSET(OPT_HIBIT_LOW)) hibit = 0;
  143.    PDEBUG(("ET4000 Clock selection: hibit = %d\n", hibit));
  144.    /* program clock */
  145.    if (OFLG_ISSET(OPT_LEGEND)) LegendClockSelect(no);
  146.    else
  147.    {
  148.      SET_CLOCKBITS_0_1(no);
  149.      Outbit_CRTC(0x34, 1, no & 0x04);                                   /* bit 2 of clock no */
  150.      if (!OFLG_ISSET(OPT_ET4000_ALTCLK))
  151.      {
  152.        Outbit_SEQ(7, 6, (hibit == 0) ? (no & 0x08) : (no & 0x08)^0x08);   /* bit 3 of clock no */
  153.      }
  154.      else
  155.      {
  156.        PDEBUG(("ET4000 clock selection: Using alternate clock selection mechanism\n"));
  157.        Outbit_SEQ(7, 6, 0); Outbit_SEQ(7, 0, 0); /* just to make sure : disable clock/2 and clock/4 */
  158.        Outbit_CRTC(0x31, 6, (hibit == 0) ? (no & 0x08) : (no & 0x08)^0x08);   /* bit 3 of clock no */
  159.        Outbit_CRTC(0x31, 7, no & 0x10);    /* bit 4 of clock no */
  160.      }
  161.    }
  162. }
  163.  
  164. void ET3000ClockSelect(int no)
  165. {
  166.   SET_CLOCKBITS_0_1(no);
  167.   Outbit_CRTC( 0x24, 1, no & 0x04); /* CS2 */
  168. }
  169.  
  170.  
  171. void CirrusClockSelect(int freq)
  172. {
  173. #if 0       /* obsoleted by XFree 3.2 Cirrus clockchip code */
  174.   /* a problem with the Cirrus Clockchip code from XFREE causes 58 MHz to be extremely unstable */
  175.   if ((freq>57900) && (freq<58100)) freq = 57900;
  176. #endif
  177.   /* set DRAM speed (MCLK) = (14318 * val / 8) */
  178.   if (OFLG_ISSET(OPT_XFAST_DRAM)) Outb_SEQ(0x1f,0x25);   /* 66.2 MHz */
  179.   if (OFLG_ISSET(OPT_FAST_DRAM))  Outb_SEQ(0x1f,0x22);   /* 60.8 MHz */
  180.   if (OFLG_ISSET(OPT_MED_DRAM))   Outb_SEQ(0x1f,0x1f);   /* 55.5 MHz */
  181.   if (OFLG_ISSET(OPT_SLOW_DRAM))  Outb_SEQ(0x1f,0x1c);   /* 50.1 MHz */
  182.  
  183.   SET_CLOCKBITS_0_1(3);
  184.   CirrusSetClock(freq);  /* must be AFTER MCLK setting, since CirrusSetClock() uses MCLK */
  185. }
  186.  
  187.  
  188.  
  189. void Video7ClockSelect(int no)
  190. {
  191.   if (no < 2) SET_CLOCKBITS_0_1(no);
  192.   else SET_CLOCKBITS_0_1(2);
  193.   outw(0xA4 | (no << 10), 0x3C4);
  194. }
  195.  
  196.  
  197. void ALIClockSelect(int chipset, int no)
  198. {
  199. #if 0
  200.   /* original XFREE code */
  201.   int temp = Inb_GR_CTL(0x0B);
  202.   (no <= 7) ? Outb_GR_CTL(0x0B, temp | 0x01) : Outb_GR_CTL(0x0B, temp & 0xFC);
  203.   SET_CLOCKBITS_0_1(no);
  204.   temp = Inb_GR_CTL(0x0C);
  205.   Outb_GR_CTL(0x0C, ((no & 0x04) << 3));
  206. #else
  207.   /* cleaned up. OK ??? */
  208.   if (chipset!=CS_AL2101)
  209.   {
  210.     /* division by 2 for low clocks */
  211.     Outbit_GR_CTL(0x0B, 0, (no <= 7) ? 1 : 0);
  212.     Outbit_GR_CTL(0x0B, 1, 0);
  213.   }
  214.   SET_CLOCKBITS_0_1(no);                       /* clock bits 0 and 1 */
  215.   Outbit_GR_CTL(0x0C, 5, no & 0x04);           /* clock bit 2 */
  216. #endif
  217.   /* is this REALLY necessary? could someone please try this out ? */
  218.   Outbit_CRTC(0x1A, 4, 0);   /* re-lock ALI ext regs --- This is NOT the good place for this */
  219. }
  220.  
  221.  
  222. void OAKClockSelect(int chipset, int no)
  223. {
  224.   if (chipset==CS_OTI87)
  225.     {
  226.       Outb_OTI(OTI87_CLOCK, no);
  227.     }
  228.   else
  229.     {
  230.       SET_CLOCKBITS_0_1(no);
  231.       Outbit_OTI(OTI_MISC, 5, no & 0x04);
  232.     }
  233.  }
  234.  
  235. void SISClockSelect(int no)
  236. {
  237.   /*
  238.    * Do CS0 and CS1 and set them - makes index 7 valid
  239.    */
  240.   SET_CLOCKBITS_0_1(3);
  241.  
  242.   Outb_SEQ(0x07, (Inb_SEQ(0x07) & 0xF0) | no);
  243. }
  244.  
  245. void RealTekClockSelect(int no)
  246. {
  247.   SET_CLOCKBITS_0_1(no);
  248.   Outbit_GR_CTL(0x0C, 5, no & 0x04); /* CS2 */
  249.   Outb_GR_CTL(0x0B, (no & 0x08) ? 0x04 : 0x02); /* CS3, which is a clock divide-by-2 */
  250. }
  251.  
  252. void ARKClockSelect(int no)
  253. {
  254.   SET_CLOCKBITS_0_1(no);
  255.   Outb_SEQ( 0x11, (Inb_SEQ(0x11) & 0x3F) | ((no & 0x0C) << 4) ); /* CS2-3 */
  256. }
  257.  
  258. void NCRClockSelect(int chipset, int no)
  259. {
  260.   SET_CLOCKBITS_0_1(no);
  261.   switch (chipset)
  262.   {
  263.     case CS_NCR22E: 
  264.         Outbit_SEQ(0x1F, 6, (no & 0x04)); /* CS2 */
  265.         break;
  266.     case CS_NCR32:
  267.         Outbit_SEQ(0x1F, 5, (no & 0x04)); /* CS2 */
  268.         Outbit_SEQ(0x1F, 6, (no & 0x08)); /* CS3 */
  269.         break;
  270.     default: PERROR(("Illegal NCR chipset\n"));
  271.   }
  272. }
  273.  
  274. void GVGAClockSelect(int no)
  275. {
  276.   SET_CLOCKBITS_0_1(no);
  277.   Outbit_SEQ( 0x7, 0, no & 0x04); /* CS2 */
  278. }
  279.  
  280. void MXClockSelect(int no)
  281. {
  282.   SET_CLOCKBITS_0_1(no);
  283.   Outbit_SEQ( 0xC4, 0, no & 0x04); /* CS2 */
  284. }
  285.  
  286.